#include "NetEnvConfigPage.h"


#include "StringListEditor.h"
#include "common.h"
#include "ConfigManager.h"
#include "CommandDispatcher.h"


NetEnvConfigPage::NetEnvConfigPage(const int pageNum) : super(pageNum), mconfigManager(ConfigManagerSingleton::instance()) {
    //ctor
}

NetEnvConfigPage::~NetEnvConfigPage() {
    //dtor
}



void NetEnvConfigPage::initEditors() {

    const NetEnvConfigInfo& netEnvConfig = mconfigManager.getNetEnvConfigInfo();
    const Utility::StringMap* pmap = &netEnvConfig.serverAddrs;
    Utility::StringMap::const_iterator iterator;
    for (iterator = pmap->cbegin(); iterator != pmap->cend(); ++iterator) {
        serverListPtr->emplace_back(iterator->first);
    }

    serverListPtr->emplace_back(KEEP_ORIGIN);
    BasicEditor* pEditor = new StringListEditor(1, 0, 15, serverListPtr);
    editUnits.push_back(BasicEditorSharedPtr(pEditor));

    pmap = &netEnvConfig.dialScripts;
    for (iterator = pmap->cbegin(); iterator != pmap->cend(); ++iterator) {
        dialScriptListPtr->emplace_back(iterator->first);
    }
    dialScriptListPtr->emplace_back(KEEP_ORIGIN);
    pEditor = new StringListEditor(3, 0, 15, dialScriptListPtr);
    editUnits.push_back(BasicEditorSharedPtr(pEditor));
}



void NetEnvConfigPage::setValue() {
    const NetEnvConfigInfo& netEnvConfig = mconfigManager.getNetEnvConfigInfo();
    const Utility::StringMap* pmap = &netEnvConfig.serverAddrs;
    Utility::StringMap::const_iterator iterator;
    for (iterator = pmap->cbegin(); iterator != pmap->cend(); ++iterator) {
        if (mserverAddr == iterator->second) {
            break;
        }
    }
    Utility::StringMap::size_type index = std::distance(pmap->cbegin(), iterator);
    static_cast<StringListEditor*> (editUnits[0].get())->setValueByRange(index);


    pmap = &netEnvConfig.dialScripts;
    for (iterator = pmap->cbegin(); iterator != pmap->cend(); ++iterator) {
        if (mdialScript == iterator->second) {
            break;
        }
    }
    index = std::distance(pmap->cbegin(), iterator);
    static_cast<StringListEditor*> (editUnits[1].get())->setValueByRange(index);

}


/**
 * 设置时间数据
 */
void NetEnvConfigPage::saveValue() {
    bool changed = false;

    Utility::StringMap::size_type index = static_cast <StringListEditor*>(editUnits[0].get())->getValue();
    if (serverListPtr->size() - 1 != index) {
        mserverAddr = mconfigManager.getNetEnvConfigInfo().serverAddrs.at((*serverListPtr)[index]);
        IpAddressInfo& serverAddress = mconfigManager.getConfigInfo().serverAddress;
        if (serverAddress.ip != mserverAddr) {
            serverAddress.ip = mserverAddr;
            CommandDispatcherSingleton::instance().resetAddressInfo(serverAddress);
            changed = true;
            mconfigManager.saveConfigInfo();
        }
    }

    index = static_cast <StringListEditor*>(editUnits[1].get())->getValue();
    if (dialScriptListPtr->size() - 1 != index) {
        const std::string dialScript = mconfigManager.getNetEnvConfigInfo().dialScripts.at((*dialScriptListPtr)[index]);
        if (dialScript != mdialScript) {
            std::string absPath = NET_ENV_DIR + dialScript;
            int returnCode = symlink(absPath.data(), DIAL_SCRIPT_SYMBOL);
            if (0 != returnCode) {
                ::remove(DIAL_SCRIPT_SYMBOL);
                returnCode = symlink(absPath.data(), DIAL_SCRIPT_SYMBOL);
            }

            if (0 != returnCode) {
                std::string messagePrefix("change dial script failed,");
                LOG_ERROR(buildErrorMessage(returnCode, errno, messagePrefix).data());
            } else {
                changed = true;
                mdialScript = dialScript;
            }
        }
    }
    if (changed) {
        CommandDispatcherSingleton::instance().notifyForReconnect();
    }

}



void NetEnvConfigPage::beforeDisplay() {
    mserverAddr = mconfigManager.getConfigInfo().serverAddress.ip;

    std::string& tempRef = mdialScript;
    tempRef.resize(STRING_BUFFER_SIZE);
    ssize_t readed = readlink(DIAL_SCRIPT_SYMBOL, &tempRef[0], tempRef.size());
    if (-1 == readed) {
        tempRef = "not linked yet";
    } else {
        tempRef.resize(readed);
        tempRef.erase(0, NET_ENV_DIR.size());
    }
}



void NetEnvConfigPage::paint() {
    if (focus) {
        EditablePage::paint();
    } else {
        std::string content[4];
        resetStream();
        strStream << "netEnv server:" << std::setw(2) << pageNum;
        content[0] = strStream.str();
        content[1] = mserverAddr;
        content[2] = "dialScript:";
        content[3] = mdialScript;
        screen.show(&content[0], &content[1], &content[2], &content[3]);
    }
}


